﻿using System;
using System.Collections.Generic;
using System.Data;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.Core.Contents.Extensions;
using Orchard.Data.Migration;
using Orchard.Environment.Extensions;

namespace Downplay.Audit
{
    public class Migrations : DataMigrationImpl
    {

        public int Create()
        {
            // Audit table
            SchemaBuilder.CreateTable("AuditRecord", table => table
                .Column("Id", DbType.Int64, column => column.PrimaryKey().Identity())
                .Column("ContentItemId", DbType.Int32)
                .Column("ContentItemVersionId", DbType.Int32)
                .Column("UserLocationId", DbType.Int64)
                .Column("AuditCode", DbType.String, col => col.WithLength(31))
                .Column("AuditData", DbType.String, col => col.Unlimited())
                .Column<DateTime>("TimeInitiated")
                .Column<DateTime>("TimeCompleted", col => col.Nullable())
                .Column("SourceUrl", DbType.String, col=>col.Unlimited())
                .Column("ReferrerUrl", DbType.String, col => col.Unlimited())
            );
            // User location table
            SchemaBuilder.CreateTable("UserLocationRecord", table => table
                .Column<long>("Id", column => column.PrimaryKey().Identity())
                .Column<int>("UserId")
                .Column("IPv4Address", DbType.String, col => col.WithLength(15))
                .Column("IPv6Address", DbType.String, col => col.WithLength(39))
                .Column("CountryCode", DbType.String, col => col.WithLength(2).WithDefault("  "))
                .Column("BrowserDetails", DbType.String, col => col.Unlimited())
                .Column("HostDetails", DbType.String, col => col.Unlimited())
                .Column<DateTime>("FirstSeen")
                .Column<DateTime>("LastSeen")
                .Column<DateTime>("LastChecked")
            );

            // Indexing
            // TODO: Profile and improve
            SchemaBuilder.AlterTable("UserLocationRecord", table => table
                .CreateIndex("StreamTerritories_UserLocation_Scan", "UserId", "IPv4Address", "IPv6Address", "LastSeen")
                );

            return 4;
        }

        public int UpdateFrom1()
        {
            SchemaBuilder.AlterTable("AuditRecord", table => table
                .AddColumn<String>("AuditData", col => col.Unlimited()));
            SchemaBuilder.AlterTable("AuditRecord", table => table
                .AlterColumn("SourceUrl", col => col.WithType(DbType.String).Unlimited()));
            SchemaBuilder.AlterTable("AuditRecord", table => table
                .AddColumn<String>("ReferrerUrl", col => col.Unlimited()));

            return 3;
        }

        public int UpdateFrom2()
        {
            SchemaBuilder.AlterTable("AuditRecord", table=>table
                .AlterColumn("SourceUrl",col=>col.WithType(DbType.String).Unlimited()));
            SchemaBuilder.AlterTable("AuditRecord", table=>table
                .AddColumn<String>("ReferrerUrl",col=>col.Unlimited()));
            return 3;
        }
        public int UpdateFrom3()
        {
            // Remove index while altering columns
            SchemaBuilder.AlterTable("UserLocationRecord", table => table
               .DropIndex("StreamTerritories_UserLocation_Scan")
               );
            SchemaBuilder.AlterTable("UserLocationRecord", table => table
                .AlterColumn("IPv4Address", col => col.WithType(DbType.String).WithLength(15)));
            SchemaBuilder.AlterTable("UserLocationRecord", table => table
                .AlterColumn("IPv6Address", col => col.WithType(DbType.String).WithLength(39)));
            // Restore index
            SchemaBuilder.AlterTable("UserLocationRecord", table => table
               .CreateIndex("StreamTerritories_UserLocation_Scan", "UserId", "IPv4Address", "IPv6Address", "LastSeen")
               );
            return 4;
        }
    }
}